package com.hs.gas.client;

import static com.hs.gas.client.Config.KEY_DEPARTMENT_ID;
import gnu.io.NoSuchPortException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.TooManyListenersException;

import org.apache.commons.lang.StringUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import com.cloudgarden.resource.SWTResourceManager;
import com.hs.gas.client.exceptions.PortBusyException;

/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class TimerClient extends org.eclipse.swt.widgets.Composite implements SerialPortEventListener, DisposeListener, MouseListener {

	private static Locale locale = new Locale("zh","CN");
	private Label status;
	private Button btnCheckInterval;
	private Button btnCheckOut;
	private Button btnCheckIn;
	private static ResourceBundle resource = ResourceBundle.getBundle("messages", locale);

	private Label labelTimerStatus;
	private Label labelStatus;
	private Browser checkResult;

	private InputStream timerInputStream;

	private static Config config = new Config();
	private SerialPort serialPort;

	private int timerStatus;
	private StringBuffer queryString;

	{
		//Register as a resource user - SWTResourceManager will
		//handle the obtaining and disposing of resources
		SWTResourceManager.registerResourceUser(this);
	}

	public TimerClient(Composite parent, int style) {
		super(parent, style);
		initGUI();
		this.addDisposeListener(this);
	}

	/**
	* Initializes the GUI.
	*/
	private void initGUI() {
		try {
			this.setSize(516, 531);
			this.setBackground(SWTResourceManager.getColor(192, 192, 192));
			this.setLayout(null);
			{
				labelTimerStatus = new Label(this, SWT.NONE);
				labelTimerStatus.setText(resource.getString("TimerStatus"));
				labelTimerStatus.setVisible(false);
			}
			{
				checkResult = new Browser(this, SWT.NONE);
				checkResult.setUrl(getUrl(null));
				checkResult.setEnabled(false);
				checkResult.setBounds(24, 126, 451, 383);
			}
			{
				btnCheckIn = new Button(this, SWT.RADIO | SWT.LEFT);
				btnCheckIn.setText(resource.getString("checkIn"));
				btnCheckIn.setBounds(28, 72, 60, 30);
				btnCheckIn.addSelectionListener(new SelectionListener() {

					public void widgetDefaultSelected(SelectionEvent arg0) {
						
					}

					public void widgetSelected(SelectionEvent arg0) {
						if(btnCheckIn.getSelection()) {
							status.setText(resource.getString("checkIn"));
							timerStatus = 1;
						}
					}
					
				});
			}
			{
				btnCheckOut = new Button(this, SWT.RADIO | SWT.LEFT);
				btnCheckOut.setText(resource.getString("checkOut"));
				btnCheckOut.setBounds(94, 72, 60, 30);
				btnCheckOut.addSelectionListener(new SelectionListener() {

					public void widgetDefaultSelected(SelectionEvent arg0) {
						
					}

					public void widgetSelected(SelectionEvent arg0) {
						if(btnCheckOut.getSelection()) {
							status.setText(resource.getString("checkOut"));
							timerStatus = 2;
						}
					}
					
				});
			}
			{
				btnCheckInterval = new Button(this, SWT.RADIO | SWT.LEFT);
				btnCheckInterval.setText(resource.getString("checkInterval"));
				btnCheckInterval.setBounds(160, 72, 60, 30);
				btnCheckInterval.addSelectionListener(new SelectionListener() {

					public void widgetDefaultSelected(SelectionEvent arg0) {
						
					}

					public void widgetSelected(SelectionEvent arg0) {
						if(btnCheckInterval.getSelection()) {
							status.setText(resource.getString("checkInterval"));
							timerStatus = 1;
						}
					}
					
				});
			}
			{
				status = new Label(this, SWT.NONE);
				status.setText("");
				status.setBounds(94, 0, 126, 61);
				status.setFont(SWTResourceManager.getFont("Tahoma", 26, 1, false, false));
			}
			{
				labelStatus = new Label(this, SWT.NONE);
				labelStatus.setText(resource.getString("status"));
				labelStatus.setBounds(28, 18, 41, 20);
			}
			this.layout();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void startCheck(Config config) throws NoSuchPortException, PortBusyException {
		serialPort = TimerUtil.initSerialPort(config);
		try {
			timerInputStream = serialPort.getInputStream();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		try {
			serialPort.addEventListener(this);
		} catch (TooManyListenersException e1) {
			e1.printStackTrace();
		}
	}

	private void stopCheck() {
		if(serialPort != null) {
			serialPort.removeEventListener();
			if(timerInputStream != null) {
				try {
					timerInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			serialPort.close();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see gnu.io.SerialPortEventListener#serialEvent(gnu.io.SerialPortEvent)
	 */
	public void serialEvent(SerialPortEvent event) {
		if( SerialPortEvent.DATA_AVAILABLE == event.getEventType()) {
			int[] dataes = new int[8];
			try {
				int data = -1;
				int i = 0;
				while((data = timerInputStream.read()) != -1) {
					if(i <= 8) {
						dataes[i] = data;
					}
					i++;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			long l = 0;
			for(int i = 3; i < 7; i++) {
				l = (l * 256) + dataes[i];
			}
			String cardNo = Long.toString(l);
			cardNo = StringUtils.leftPad(cardNo, 10, '0');
			queryString = new StringBuffer();
			queryString.append(config.getFullApplicationUrl());
			queryString.append("/timerListener!idCardChecking.action?department.id=");
			queryString.append(config.get(KEY_DEPARTMENT_ID));
			queryString.append("&cardNo=");
			queryString.append(cardNo);
			queryString.append("&timerStatus=");
			queryString.append(timerStatus);
			queryString.append("&clientTime=");
			queryString.append(System.currentTimeMillis());
			System.out.println(queryString);
			getDisplay().syncExec(new Runnable() {

				public void run() {
					checkResult.setUrl(queryString.toString());
				}
				
			});
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
	 */
	public void widgetDisposed(DisposeEvent e) {
		stopCheck();
	}

	private String getUrl(String info) {
		StringBuffer sb = new StringBuffer();
		sb.append(config.getFullApplicationUrl());
		sb.append("/timerListener.action");
		if(info != null) {
			sb.append("?info=");
			sb.append(info);
			sb.append("&department.id=");
			sb.append(config.get(Config.KEY_DEPARTMENT_ID));
		}
		return sb.toString();
	}

	/**
	* Auto-generated main method to display this 
	* org.eclipse.swt.widgets.Composite inside a new Shell.
	*/
	public static void main(String[] args) {
		Display display = Display.getDefault();
		Shell shell = new Shell(display);
		TimerClient inst = new TimerClient(shell, SWT.NULL);

		Point size = inst.getSize();
		shell.setLayout(new FillLayout());
		shell.setText(resource.getString("TimerClient"));
		shell.layout();
		if(size.x == 0 && size.y == 0) {
			inst.pack();
			shell.pack();
		} else {
			Rectangle shellBounds = shell.computeTrim(0, 0, size.x, size.y);
			shell.setSize(shellBounds.width, shellBounds.height);
		}
		shell.open();

		try {
			inst.startCheck(config);
		} catch (NoSuchPortException e) {
			e.printStackTrace();
		} catch (PortBusyException e) {
			e.printStackTrace();
		}

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}

	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseDoubleClick(MouseEvent e) {
		
	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseDown(MouseEvent e) {
		
	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseUp(MouseEvent e) {
		stopCheck();
		try {
			startCheck(config);
		} catch (NoSuchPortException e1) {
			e1.printStackTrace();
		} catch (PortBusyException e1) {
			e1.printStackTrace();
		}
	}

}
